// 1.函数声明定义
function sum(x : number, y : number) : number {
     return x + y;
}
console.log(sum(2,4));

//2.函数表达式 这里的=>表示 用来表示函数的定义，左边是输入类型，需要用括号括起来，右边是输出类型。
// 函数类型包含两部分：参数类型和返回值类型 完整函数类型：必须有返回值，没有就用void

// let mySum : (x : number, y : number) => number = function (x : number, y : number):number {
//     return x + y;
// };

//可以类型推倒函数
let mySum  = function (x : number, y : number):number {
    return x + y;
};
console.log(mySum(4,5));




//3，接口定义函数
interface ISearchFunc {
    (source : string, substring : string):boolean;
};

let  searchfunc : ISearchFunc;
searchfunc = function (source : string, substring : string) {
     return source.search(substring) != -1;
};
console.log(searchfunc("2334455",'45'));


// 4.可选参数 和默认值参数
// 可选参数后面不允许再出现必须参数了
// 默认参数：默认值的参数识别为可选参数
// ...rest 的方式获取函数中的剩余参数 字符串数组

function buildName( firstName:string, lastName?:string, age : number = 10,...items:string[]) {
    
      console.log(items);

      if(lastName){
          return firstName + '加上' + lastName + '数字' + age.toString();
      }else {
          return firstName + age.toString();
      }

}
console.log((buildName("tom","455",23,'5',"45","法国队和规范")));


// 5.函数重载
// TypeScript 会优先从最前面的函数定义开始匹配，所以多个函数定义如果有包含关系，需要优先把精确的定义写在前面
function reverse(x : number): number;
function reverse(x : string): string;
function reverse(x : number|string): number | string{
      if(typeof x === "number"){
             return Number(x.toString().split('').reverse().join(''));
      }else {
             return x.toString().split('').reverse().join('');
      }
};


// 6.泛型接口函数
interface ICreateArrayFunc <T>{
    (leng:number,value : T):Array<T>;
};

let createArrayFunc : ICreateArrayFunc <any>;
createArrayFunc = function <T>(leng:number, value :T) : Array<T> {
    let  result : T[] = [];
    for (let i = 0; i < leng; i++) {
        result[i] = value;
    }

    return result;
};
console.log(createArrayFunc(3, 'x')); // ['x', 'x', 'x']


